package com.zhugy.comparecode.c;

import java.util.List;

import com.zhugy.comparecode.BaseCodeFile;
import com.zhugy.comparecode.CodeFile;
import com.zhugy.comparecode.CodeLine;
import com.zhugy.comparecode.CompareResult;
import com.zhugy.comparecode.config.CompareConfig;
import com.zhugy.comparecode.util.CommonUtils;

public class CFile extends BaseCodeFile {

	public CFile(String baseDir, String relativePath) {
		super(baseDir, relativePath);
	}

	@Override
	protected CodeLine parseLineWithContent(String content, int index) {
		if (CommonUtils.isEmpty(content)) {
			return null;
		}
		int indexOfDoubleSlash = content.indexOf("//");
		if (indexOfDoubleSlash >= 0) {
			return new CCodeLine(index, content.substring(0, indexOfDoubleSlash));
		}
		int indexOfMultiLineComment = content.indexOf("/*");
		if (indexOfMultiLineComment >= 0) {

		}
		return new CCodeLine(index, content);
	}

	@Override
	protected boolean isBlankLine(String content) {
		if (CommonUtils.isEmpty(content)) {
			return true;
		}
		if (isInMultiLineComment) {
			int indexOfClose = content.indexOf("*/");
			if (indexOfClose < 0) {
				return true;
			}
			String contentWithoutComment = content.substring(indexOfClose + 2);
			return checkIsBlank(contentWithoutComment);
		}
		if (content.startsWith("//")) {
			return true;
		}
		if (content.startsWith("/*")) {
			int indexOfClose = content.indexOf("*/");
			if (indexOfClose < 0) {
				return true;
			}
			String contentWithoutComment = content.substring(indexOfClose + 2);
			return checkIsBlank(contentWithoutComment);
		}
		return false;
	}

	protected void updateInMultiLineComment(String lineAfterTrim) {
		// 在多行注释里
		if (isInMultiLineComment) {
			int indexOfClose = lineAfterTrim.indexOf("*/");
			if (indexOfClose < 0) {
				return;
			}
			String remain = lineAfterTrim.substring(indexOfClose + 2);
			int indexOfMultiComment = lineAfterTrim.indexOf("/*");
			if (indexOfMultiComment < 0) {
				isInMultiLineComment = false;
				return;
			}
			updateInMultiLineComment(remain);
			return;
		}
		// 没有在多行注释
		int indexOfMultiComment = lineAfterTrim.indexOf("/*");
		if (indexOfMultiComment < 0) {
			return;
		}
		int indexOfClose = lineAfterTrim.indexOf("*/");
		// 没有结束
		if (indexOfClose < 0) {
			isInMultiLineComment = true;
			return;
		}
		String remain = lineAfterTrim.substring(indexOfClose + 2);
		updateInMultiLineComment(remain);
	}

	private boolean checkIsBlank(String content) {
		if (CommonUtils.isEmpty(content)) {
			return true;
		}
		if (content.startsWith("//")) {
			return true;
		}
		if (content.startsWith("/*")) {
			int indexOfClose = content.indexOf("*/");
			if (indexOfClose < 0) {
				isInMultiLineComment = true;
				return true;
			}
			isInMultiLineComment = false;
			String contentWithoutComment = content.substring(indexOfClose + 2);
			return checkIsBlank(contentWithoutComment);
		}
		return false;
	}

	@Override
	public CompareResult compareTo(CodeFile cf, CompareConfig config) {
		List<CodeLine> codeLines1 = this.lines();
		List<CodeLine> codeLines2 = cf.lines();
		if (CommonUtils.isEmpty(codeLines1)) {
			if (CommonUtils.isEmpty(codeLines2)) {
				return CompareResult.success("");
			}
			return CompareResult.fail("文件1有行数，而文件2没有");
		}
		if (CommonUtils.isEmpty(codeLines2)) {
			return CompareResult.fail("文件2有行数，而文件1没有");
		}
		int compareLines1 = 0, compareLines2 = 0;
		
		if (!(codeLines2.get(0) instanceof CCodeLine)) {
			return CompareResult.fail("文件2的第" + (compareLines2 + 1) + "行不是C语言行");
		}
		CCodeLine curLine2 = (CCodeLine) codeLines2.get(compareLines2);
		int part2Index = 0;
		String[] curParts2 = curLine2.getParts();
		for (; compareLines1 < codeLines1.size(); compareLines1++) {
			if (!(codeLines1.get(compareLines1) instanceof CCodeLine)) {
				return CompareResult.fail("文件1的第" + (compareLines1 + 1) + "行不是C语言行");
			}
			CCodeLine curLine1 = (CCodeLine) codeLines1.get(compareLines1);
			String[] parts1 = curLine1.getParts();
			for (int i = 0; i < parts1.length; i++) {
				String part2;
				if (part2Index < curParts2.length) {
					part2 = curParts2[part2Index];
				} else {
					if (compareLines2 >= codeLines2.size() - 1) {
						return CompareResult.fail("文本2已经在第：" + curLine2.index() + "行结束，但文本1还没结束");
					}
					compareLines2++;
					curLine2 = (CCodeLine) codeLines2.get(compareLines2);
					curParts2 = curLine2.getParts();
					part2Index = 0;
					part2 = curParts2[part2Index];
				}
				if (!CommonUtils.equals(parts1[i], part2)) {
					if (config.isIgnoreLine1(relativeName(), curLine1.index())) {
						System.out.println("文本1的第" + curLine1.index() + "行第" + (i+1) + "部分" +
								"跟文本2的第" + curLine2.index()  + "第" + (part2Index) + "部分不同，但忽略");
						compareLines2++;
						curLine2 = (CCodeLine) codeLines2.get(compareLines2);
						curParts2 = curLine2.getParts();
						part2Index = 0;
						part2 = curParts2[part2Index];
						break;
					}
					if (config.isIgnoreLine2(cf.relativeName(), curLine2.index())) {
						System.out.println("文本1的第" + curLine1.index() + "行第" + (i+1) + "部分" +
								"跟文本2的第" + curLine2.index()  + "第" + (part2Index) + "部分不同，但忽略");
						compareLines2++;
						curLine2 = (CCodeLine) codeLines2.get(compareLines2);
						curParts2 = curLine2.getParts();
						part2Index = 0;
						part2 = curParts2[part2Index];
						break;
					}
					return CompareResult.fail("文本1的第" + curLine1.index() + "行第" + (i+1) + "部分["+ parts1[i] +
							"]跟文本2的第" + curLine2.index()   + "第" + (part2Index + 1) + "部分["
							+ part2 + "]不同");
				}
				part2Index++;
			}
		}
		
		if (part2Index < curParts2.length - 1) {
			return CompareResult.fail("文本1已经结束，但文本2还有内容，文本2到第" + compareLines2 + "行第" + part2Index + "部分");
		}
		
		if (compareLines2 < codeLines2.size() - 1) {
			return CompareResult.fail("文本1已经结束，但文本2还有内容，文本2到第" + compareLines2 + "行第" + part2Index + "部分");
		}
		return CompareResult.success("");
	}

}
